package com.example.test;

import cn.hutool.Hutool;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.example.test.entity.User;
import com.example.test.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
public class RedisController {


    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    IUserService iUserService;

    /**
     * @Description 首先从数据库获取, 获取不到从数据库查询并放入redis中
     * @Author FL
     * @Date 11:27 2021/9/3
     * @Param [key]
     **/
    @GetMapping("/getData")
    public String getData(String key) {

        String value = redisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(value)) {
            return value;
        }
        User user = iUserService.getById(key);
        if (null != user) {
            String name = user.getName();
            redisTemplate.opsForValue().set("name", name);
            return name;
        }
        redisTemplate.opsForValue().set("name", "");
        return "";
    }


    /**
     * @Description 单个服务加锁
     * @Author FL
     * @Date 11:28 2021/9/3
     * @Param [key]
     **/
    @GetMapping("/getDataSingle")
    public String getDataSingle(String key) {


        String value = "";
        value = redisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(value)) {
            return value;
        }

        synchronized (this) {
            // 再次检查
            value = redisTemplate.opsForValue().get(key);
            if (StrUtil.isNotBlank(value)) {
                return value;
            }

            User user = iUserService.getById(key);
            if (null != user) {
                String name = user.getName();
                redisTemplate.opsForValue().set("name", name);
                return name;
            }
            redisTemplate.opsForValue().set("name", "");
            return "";
        }
    }



    /**
     * @Description 分布式部署采用分布式锁
     * @Author FL
     * @Date 11:32 2021/9/3
     * @Param [key]
     **/
    @GetMapping("/getDataCluster")
    public String getDataCluster(String key) {

        String value = "";
        value = redisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(value)) {
            return value;
        }
        for(;;){
            if (redisTemplate.opsForValue().setIfAbsent(key, IdUtil.randomUUID(),1000L, TimeUnit.MILLISECONDS)) {
                // 再次检查
                value = redisTemplate.opsForValue().get(key);
                if (StrUtil.isNotBlank(value)) {
                    return value;
                }

                User user = iUserService.getById(key);
                if (null != user) {
                    String name = user.getName();
                    redisTemplate.opsForValue().set("name", name);
                    return name;
                }
                redisTemplate.opsForValue().set("name", "");
                return "";
            }else {
                Thread.yield();
            }
        }
    }

}
